/*
 * @Author: xuetao 3168581151@qq.com
 * @Date: 2025-02-22
 * @LastEditors: xuetao 3168581151@qq.com
 * @LastEditTime: 2025-04-16
 * @Description: 移动端
 */
import 'dart:io';
import 'package:flutter/material.dart' show debugPrint, Color, Colors;
import 'package:flutter/services.dart';
// 图片插件
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart' show ImagePicker, ImageSource;

// 常量配置
const _kMaxFileSize = 5 * 1024 * 1024; // 5MB
const _kCompressionInitialQuality = 90;
const _kCompressionQualityStep = 10;
const _kMinCompressionQuality = 50;
const _kImageSize = 800;

final _picker = ImagePicker();

/// 完整图片处理流程
Future<XFile?> processImage(bool enableFreeStyle) async {
  try {
    // 1. 选择图片
    final pickedFile = await _pickImageFromGallery();
    if (pickedFile == null) return null;

    // 2. 裁剪图片
    final croppedFile =
        await _cropImage(File(pickedFile.path), enableFreeStyle);
    if (croppedFile == null) return null;

    // 3. 压缩图片
    return await _compressImageIfNeeded(croppedFile);
  } on ImageProcessingException catch (e) {
    debugPrint('图片处理失败: ${e.message}');
    return null;
  } catch (e) {
    debugPrint('未知错误: $e');
    return null;
  }
}

/// 裁剪图片
Future<File?> _cropImage(File originalFile, bool enableFreeStyle) async {
  try {
    final cropped = await ImageCropper().cropImage(
      sourcePath: originalFile.path,
      aspectRatio:
          enableFreeStyle ? null : const CropAspectRatio(ratioX: 1, ratioY: 1),
      compressQuality: 100,
      uiSettings: [
        AndroidUiSettings(
          toolbarTitle: '裁剪图片',
          toolbarColor: const Color(0xFFABAFF5),
          toolbarWidgetColor: Colors.white,
          statusBarColor: const Color(0xFFABAFF5).withValues(alpha: .8),
          hideBottomControls: true,
          initAspectRatio: CropAspectRatioPreset.square,
          aspectRatioPresets: enableFreeStyle
              ? [
                  CropAspectRatioPreset.original,
                ] // 自由模式
              : [CropAspectRatioPreset.square], // 限制模式只显示正方形
        ),
      ],
    );
    return cropped != null ? File(cropped.path) : null;
  } on PlatformException catch (e) {
    throw ImageProcessingException('裁剪失败: ${e.message}');
  }
}

/// 智能图片压缩
Future<XFile?> _compressImageIfNeeded(File file) async {
  try {
    // 检查原始文件大小
    final fileSize = await file.length();
    if (fileSize <= _kMaxFileSize) {
      return XFile(file.path);
    }

    Uint8List bytes = await file.readAsBytes();
    if (bytes.isEmpty) throw ImageProcessingException('无效的图片文件');

    int quality = _kCompressionInitialQuality;
    while (bytes.lengthInBytes > _kMaxFileSize &&
        quality >= _kMinCompressionQuality) {
      bytes = await _compressImageBytes(bytes, quality);
      quality -= _kCompressionQualityStep;
    }

    if (bytes.lengthInBytes > _kMaxFileSize) {
      throw ImageProcessingException('图片过大，请选择更小的图片');
    }

    /// 创建临时文件
    final tempDir = Directory.systemTemp;
    final tempFile = File(
      '${tempDir.path}/compressed_${DateTime.now().millisecondsSinceEpoch}.jpg',
    );
    await tempFile.writeAsBytes(bytes);
    return XFile(tempFile.path);
  } on PlatformException catch (e) {
    throw ImageProcessingException('压缩失败: ${e.message}');
  }
}

/// 执行字节压缩
Future<Uint8List> _compressImageBytes(Uint8List bytes, int quality) async {
  final result = await FlutterImageCompress.compressWithList(
    bytes,
    quality: quality,
    minHeight: _kImageSize,
    minWidth: _kImageSize,
  );
  if (result.isEmpty) throw ImageProcessingException('图片压缩失败');
  return result;
}

/// 从相册选择图片
Future<XFile?> _pickImageFromGallery() async {
  try {
    return await _picker.pickImage(
      source: ImageSource.gallery,
      imageQuality: 100,
    );
  } on PlatformException catch (e) {
    throw ImageProcessingException('图片选择失败: ${e.message}');
  }
}

/// 从相机拍摄选择图片
Future<XFile?> pickImageFromCamera() async {
  try {
    return await _picker.pickImage(
      source: ImageSource.camera,
      imageQuality: 100,
    );
  } on PlatformException catch (e) {
    throw ImageProcessingException('图片拍摄失败: ${e.message}');
  }
}

// 上传完成后，文件内存释放 清理临时文件
Future<void> cleanTempFiles(XFile? file) async {
  if (file == null) return;
  // 删除本地文件
  try {
    final fileToDelete = File(file.path);
    if (await fileToDelete.exists()) await fileToDelete.delete();
  } catch (e) {
    debugPrint('文件清理失败: $e');
  }
}

/// 自定义图片处理异常
class ImageProcessingException implements Exception {
  final String message;
  ImageProcessingException(this.message);

  @override
  String toString() => 'ImageProcessingException: $message';
}
